package utn.tsb.tsbxml;

import com.trolltech.qt.core.Qt.SortOrder;
import com.trolltech.qt.gui.*;
import com.trolltech.qt.core.*;
import java.util.HashMap;
import java.util.Set;

public class TreeContainer extends QFrame {

    private QTreeWidget tree;
    private QPushButton btnAdd;
    private QPushButton btnRemove;
    private QPushButton btnEdit;
    private NodeContent nodeContent;

    public TreeContainer(NodeContent content){
        this.setObjectName("panel");
        this.nodeContent = content;
        QVBoxLayout vbox = new QVBoxLayout(this);
        this.tree = new QTreeWidget();
        this.tree.header().setHidden(true);
        this.tree.setSelectionMode(QTreeWidget.SelectionMode.SingleSelection);
        this.tree.setAnimated(true);
        this.tree.header().setHorizontalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel);
        this.tree.header().setResizeMode(0, QHeaderView.ResizeMode.ResizeToContents);
        this.tree.header().setStretchLastSection(false);
        vbox.addWidget(this.tree);
        QHBoxLayout hbox = new QHBoxLayout();
        this.btnAdd = new QPushButton(this.style().standardIcon(QStyle.StandardPixmap.SP_ArrowRight), "Agregar");
        this.btnRemove = new QPushButton(this.style().standardIcon(QStyle.StandardPixmap.SP_TrashIcon), "Remover");
        this.btnEdit = new QPushButton(this.style().standardIcon(QStyle.StandardPixmap.SP_FileDialogInfoView), "Editar");
        hbox.addWidget(this.btnRemove);
        hbox.addWidget(this.btnAdd);
        hbox.addWidget(this.btnEdit);
        vbox.addLayout(hbox);

        this.btnRemove.clicked.connect(this, "removeNode()");
        this.btnAdd.clicked.connect(this, "addNode()");
        this.btnEdit.clicked.connect(this, "editNode()");
        this.tree.currentItemChanged.connect(this, "hideEdit()");
    }

    private void hideEdit(){
        this.nodeContent.hide();
    }

    private void editNode(){
        TreeNode item = (TreeNode) this.tree.currentItem();
        if(item != null){
            this.nodeContent.loadData(item);
            this.nodeContent.show();
        }
    }

    public void clear(){
        this.tree.clear();
    }

    public void newRootNode(){
        String name = QInputDialog.getText(this, "Nuevo Nodo", "Nombre del Nodo:");
        if(name != null && name.trim().length() > 0){
            TreeNode item = new TreeNode(this.tree);
            item.setText(0, name);
            item.setIcon(0, this.style().standardIcon(QStyle.StandardPixmap.SP_FileIcon));
            item.createTooltip();
            this.tree.sortByColumn(0, SortOrder.AscendingOrder);
        }
    }

    public void addNode(){
        TreeNode itemParent = (TreeNode) this.tree.currentItem();
        String name = QInputDialog.getText(this, "Nuevo Nodo", "Nombre del Nodo:");
        if(itemParent != null && name != null && name.trim().length() > 0){
            TreeNode item = new TreeNode(itemParent);
            item.setText(0, name);
            item.setIcon(0, this.style().standardIcon(QStyle.StandardPixmap.SP_FileIcon));
            item.createTooltip();
            itemParent.setIcon(0, this.style().standardIcon(QStyle.StandardPixmap.SP_DirIcon));
            itemParent.setValue("");
            this.tree.sortByColumn(0, SortOrder.AscendingOrder);
        }
    }

    public void removeNode(){
        QTreeWidgetItem itemParent = this.tree.currentItem();
        if(itemParent.parent() != null){
            itemParent.parent().removeChild(itemParent);
        }else{
            int index = this.tree.indexOfTopLevelItem(itemParent);
            this.tree.takeTopLevelItem(index);
        }
    }

    public void loadTree(Nodo nodo){
        if(nodo.getName() == null){
            for(Nodo n : nodo.getNodos()){
                TreeNode parent = new TreeNode(this.tree);
                this.loadStructure(n, parent);
            }
        }
    }

    private void loadStructure(Nodo nodo, TreeNode parent){
        parent.setText(0, nodo.getName());
        parent.setIcon(0, this.style().standardIcon(QStyle.StandardPixmap.SP_FileIcon));
        parent.setValue(nodo.getValue());
        parent.setAttributes(nodo.getAttributes());
        if(!nodo.getAttributes().isEmpty()){
            parent.setForeground(0, new QBrush(new QColor(Qt.GlobalColor.blue)));
        }
        parent.createTooltip();
        if(nodo.getNodos().size() > 0){
            parent.setValue("");
            parent.setIcon(0, this.style().standardIcon(QStyle.StandardPixmap.SP_DirIcon));
            for(Nodo n : nodo.getNodos()){
                TreeNode item = new TreeNode(parent);
                this.loadStructure(n, item);
            }
        }
    }

    public String getXmlStructure(){
        StringBuilder xml = new StringBuilder();

        for(int i = 0; i < this.tree.topLevelItemCount(); i++){
            TreeNode item = (TreeNode) this.tree.topLevelItem(i);
            StringBuilder atts = new StringBuilder();
            Set<String> keys = item.getAttributes().keySet();
            String[] array = keys.toArray(new String[0]);
            for(int j = 0; j < array.length; j++){
                String att = array[j] + "=" + item.getAttributes().get(array[j]);
                atts.append(" " + att);
            }
            xml.append("<" + item.text(0) + atts.toString() + ">");
            for(int q = 0; q < item.childCount(); q++){
                xml.append("\n");
                xml.append(this.parseSubNodes((TreeNode) item.child(q), 1));
            }
            if(item.childCount() != 0){
                xml.append("\n");
            }

            if(item.childCount() == 0){
                xml.append(item.getValue());
                xml.append("</" + item.text(0) + ">");
            }else{
                xml.append("</" + item.text(0) + ">\n");
            }
        }

        return xml.toString();
    }

    private String parseSubNodes(TreeNode node, int deep){
        StringBuilder xml = new StringBuilder();
        String indent = "";
        for(int i=0; i < (4*deep); i++){
            indent += " ";
        }

        StringBuilder atts = new StringBuilder();
        Set<String> keys = node.getAttributes().keySet();
        String[] array = keys.toArray(new String[0]);
        for(int j = 0; j < array.length; j++){
            String att = array[j] + "=" + node.getAttributes().get(array[j]);
            atts.append(" " + att);
        }
        xml.append(indent + "<" + node.text(0) + atts.toString() + ">");
        for(int q = 0; q < node.childCount(); q++){
            xml.append("\n");
            xml.append(this.parseSubNodes((TreeNode) node.child(q), deep + 1));
        }
        if(node.childCount() != 0){
            xml.append("\n");
        }

        if(node.childCount() == 0){
            xml.append(node.getValue());
            xml.append("</" + node.text(0) + ">");
        }else{
            xml.append(indent + "</" + node.text(0) + ">");
        }

        return xml.toString();
    }

}
